package com.sz.common.core.service.aop;

import com.sz.common.base.dao.annotation.JudgeEntity;
import com.sz.common.base.dao.annotation.UniqueField;
import com.sz.common.base.dao.ext.DaoExt;
import com.sz.common.base.dao.ext.FieldExpBuilder;
import com.sz.common.base.dao.ext.Operator;
import com.sz.common.base.dao.utils.SqlUtil;
import com.sz.common.base.entity.EntityBase;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.core.constants.SysErrorCodes;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Map;

@Aspect
@Component
public class SysJudgeAspect {
    private Logger logger = Logger.getLogger(getClass());

    @Autowired
    protected DaoExt dao;

    @Pointcut("@annotation(com.sz.common.core.service.aop.JudgeAspect)")
    public void judge() {
    }

    @Before("judge()")
    public void doBefore(JoinPoint jp) throws Throwable {
        Object[] args = jp.getArgs();
        if (args != null && args.length > 0) {
            for (Object obj : args) {
                if (obj == null || "".equals(obj)) {
                    continue;
                }
                Class clz = obj.getClass();
                String tableName = SqlUtil.getTableName(clz);//获取表名
                if (!clz.getPackage().getName().contains("hna") || tableName == null || !(obj instanceof EntityBase)) {
                    //如果非自定义类，没有@Table注解,不是BaseObject的子类,不做判断
                    continue;
                }
                Map<String, Serializable> map = SqlUtil.getPramList((EntityBase) obj);
                JudgeEntity entity = SqlUtil.getConditions(clz);
                if (entity == null) {
                    continue;
                }
                UniqueField[] uniqueFields = entity.fieldOfSelectConditions();
                for (UniqueField uniqueField : uniqueFields) {
                    String[] fields = uniqueField.value();
                    FieldExpBuilder builder = FieldExpBuilder.add();
                    if (entity.isDeleted()) { //是否有软删除
                        builder.add("isDeleted", false);
                    }
                    if (map.get(entity.key()) != null) { //更新时,添加id判断
                        builder.add(entity.key(), Operator.NEQ, map.get(entity.key()), null);
                    }
                    for (int i = 0; i < fields.length; i++) {
                        builder.add(fields[i], map.get(fields[i]));
                    }

                    long count = dao.selectCount(tableName, builder.getFields());
                    if (count > 0) {
                        throw Exceptions.bizException(SysErrorCodes.ERROR_ARGUMENT_EXIST, StringUtils.join(fields, ","));
                    }
                }
            }
        }
    }


    @AfterReturning(returning = "ret", pointcut = "judge()")
    public void doAfterReturning(Object ret) throws Throwable {
        logger.info("RESPONSE : " + ret);
    }

    //声明环绕通知
    @Around("judge()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入方法---环绕通知");
        Object o = pjp.proceed();
        System.out.println("退出方法---环绕通知");
        return o;
    }

}